/*******************************************************
> Copyright (C) 2024 ==IOT== All rights reserved.
> File Name: smart_pointer.cpp
> Author: IOT
> Website:www.slq.org
> Created Time: 2024年10月31日 星期四 14时19分24秒
***************************************************/

#include <iostream>
#include <memory>

using namespace std;
class Array {
	int *ptr = nullptr;
	int len = 0;
	public:
		Array(int n) : len(n)
		{
			cout << "call array construtor" << endl;
			ptr = new int[n];
		}
		~Array()
		{
			cout << "call array destrutor" << endl;
			if (ptr) {
				delete [] ptr;
			}
		}
		int& operator[](int index)
		{
			return ptr[index];
		}
		void show ()
		{
			cout << "*** call show ***" << endl;
		}
};
// 定义自己的的智能指针类模板
template <class T>
class SmartPointer {
	static int share_cnt; // 类内声明,静态变量，由该类实例化出来的各个对象共享
	T *ptr = nullptr;
	public:
		SmartPointer() : ptr(nullptr)
		{}
		SmartPointer(T *_ptr) : ptr(_ptr)
		{
			cout << "call smart_pointer construtor" << endl;
		}
		~SmartPointer()
		{
			cout << "call smart_pointer destrutor: share_cnt:" << share_cnt << endl;
			share_cnt--;
			if (ptr && share_cnt == 0)
			//if (ptr)
				delete ptr;
		}
		// 拷贝构造
		
		T* operator->()
		{
			return ptr;
		}
		T& operator*()
		{
			return *ptr;
		}
		
		void operator=(SmartPointer &sp) = delete; // 显式禁止使用=运算符重载

		
		#if 0
private:
		void operator=(SmartPointer &sp)
		{
			share_cnt++;
			this->ptr = sp.ptr;
			//sp.ptr = nullptr;
		}
		#endif
		
};

template <class T>
int SmartPointer<T>::share_cnt = 1; // 类外定义

// 全局自定义函数，用于类的测试
void test_func()
{
	SmartPointer<Array> sp(new Array(5)); // 通过SmartPointer类实例化智能指针对象，并且传入另外一个对象的指针
	
	sp->show();
	(*sp).show();
	#if 0
	//Array arr(5); // 类对象
	Array *parr = new Array(5);
	
	*parr;
	parr->
	
	delete parr;
	#endif
	
	cout << "test function exit" << endl;
}

int main(int argc,const char* argv[])
{
	//test_func();
	//cout << "main over" << endl;
	
	#if 0
	int *p1 = new int(10);
	int *p2 = p1;
	cout << *p2 << endl;
	#endif
	
	SmartPointer<int> p1(new int(10));
	SmartPointer<int> p2;
	p2 = p1;
	cout << *p2 << endl;
	
	#if 0
	auto_ptr<int> p3(new int(0)); // auto_ptr是由STL提供的智能指针类模板, 不能再使用
	*p3.get() = 12;
	auto_ptr<int> p4;
	p4 = p3;
	cout << *p3 << endl;// 段错误,指向关系被转移到了p4,p3指向空，所以段错误。
	#endif
	
	shared_ptr<int> p3(new int(0)); // shared_ptr是由STL提供的智能指针类模板
	*p3.get() = 12;
	shared_ptr<int> p4;
	p4 = p3;
	cout << *p3 << "," << *p4 << endl;	//p3和p4都可以访问，如何做到double free的呢?
	
	unique_ptr<int> p5(new int(0));
	unique_ptr<int> p6;
	p6 = p5;
	
    return 0;
}

